#!/Users/timmenzies/opt/gawk/bin/gawk -f 
 
# abcd.awk
# Revision: 68
# Built by timmenzies on Wed Jun 29 03:36:15 EDT 2011.

#   _ _ _                                               ((
#  |=|=|=|.----------------------------------------.    _))_
#  |-|-|-|| AWK code of a tiny book on data mining | ___\__/)_
#  |_|_|_|'----------------------------------------| |_|_~~_|_|

# This file is part of TINY.
#
# TINY is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# TINY is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
#  along with TINY.  If not, see <http://www.gnu.org/licenses/>.

 BEGIN { OFS="," }
 /^#/  { next}
       { update($1,$2) }
 END   { header()
         for(K in Klass) 
            report(K,A[K],B[K],C[K],D[K]) }

 function header() {
     print "#a,b,c,d,acc,pd,prec,pf,f,g,pn,klass"
 }
 function update(actual, predicted,    target) {
      known(actual)
	  known(predicted)
 	  if(actual==predicted) { Yes++ } else { No++ }
       for(target in Klass)  
         if (actual==target) { 
            predicted==actual ? D[target]++ : B[target]++
          } else { 
            predicted==target ? C[target]++ : A[target]++ }
 }    
 function known(k) {
	if (++Klass[k]==1) # first time we have seen this so all prior
		A[k]=Yes+No    # results are not(k) being classified not(k)
 }
 function report(k,a,b,c,d,   acc,pd,pf,prec,f,g,pn) {
     acc = pd = pf = prec = f = g = pn = 0
     if (b+d)  pd   = d     / (b+d)
     if (a+c)  pf   = c     / (a+c)
     if (a+c)  pn   = (b+d) / (a+c)
     if (c+d)  prec = d     / (c+d)
     if (1-pf+pd) g = 2*(1-pf)*pd   / (1-pf+pd)
     if (prec+pd) f = 2*prec*pd / (prec+pd)
 	if (Yes+No) acc = Yes  / (Yes+No)
 	print  a,b,c,d,p(acc),\
           p(pd),p(prec),p(pf),p(f),p(g),\
           sprintf("%.2f",pn),k | "sort -t, -n -k 9"
 }
 function p (x) { return int(100*x + 0.5) }

